package com.xunwulian.cmpp.client.handler;

import com.alibaba.dubbo.config.annotation.Reference;
import com.google.common.base.Preconditions;
import com.google.gson.Gson;
import com.xunwulian.api.iface.AppAPI;
import com.xunwulian.base.entity.AppEntity;
import com.xunwulian.cmpp.sms.PDU;
import com.xunwulian.cmpp.util.CmppConstant;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

@Component
public class CmppClient {

    private static final Logger logger = LoggerFactory.getLogger(CmppClient.class);
    private ConnectFuture connectFuture = null;
    public AppEntity app;

    @Reference
    private AppAPI appAPI;

    @Autowired
    private CmppClientIoHandler ioHandler;

    public AppEntity getApp() {

        // 获取环境变量，平台ID
        String appId = System.getenv("appId");
        if (appId == null || "".equals(appId)) {
            appId = "mock";
        }
        logger.info("appId:" + appId);

        // zk地址
        String registryAddress = System.getenv("registry");
        if (registryAddress == null || "".equals(registryAddress)) {
            registryAddress = "zookeeper://127.0.0.1:2181";
        }
        logger.info("registryAddress:" + registryAddress);

        AppEntity appEntity;
        if ("mock".equals(appId)) {
            appEntity = new AppEntity();
            appEntity.setAppId("mockAppId");
            appEntity.setRegistryAddress("zookeeper://127.0.0.1:2181");
            appEntity.setServerClientId("mockClientId");
            appEntity.setClientSecret("mockClientSecret");
            appEntity.setServerIp("127.0.0.1");
            appEntity.setServerPort("7890");
            appEntity.setDubboPort("20880");
        } else {
            appEntity = (AppEntity) appAPI.getApp(appId).getData();
            logger.info(new Gson().toJson(appEntity));
        }

        return appEntity;
    }

    public void start() {
        Preconditions.checkNotNull(app);

        new Thread(() -> {
            try {
                if (connectFuture != null) {
                    connectFuture.getSession().close();
                }
                connectFuture = null;
                IoConnector connector = new NioSocketConnector();
                connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CmppProtocolCodecFactory()));
                ioHandler.setApp(app);
                connector.setHandler(ioHandler);
                connector.setConnectTimeoutMillis(30000);
                connectFuture = connector.connect(new InetSocketAddress(app.getServerIp(), Integer.valueOf(app.getServerPort())));
                logger.info("connecting to server:" + app.getServerIp() + ":" + app.getServerPort());
                connectFuture.awaitUninterruptibly();
                connectFuture.getSession().getCloseFuture().awaitUninterruptibly();
                connector.dispose();
                Thread.sleep(2000 + CmppConstant.HEARTBEAT_INTERVAL * CmppConstant.HEARTBEAT_RETRY);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

    public void sendMessage(PDU pdu) {
        connectFuture.getSession().write(pdu);
    }

    public void runService() {
//        ClassPathXmlApplicationContext context =
//                new ClassPathXmlApplicationContext("classpath:ApplicationContext-cmpp-client.xml");

        // 提供的Cmeb服务
//        CmppCmebAPI cmppCmebAPI = (CmppCmebAPI) context.getBean("cmppCmebApi");
//        new Provider<>(cmppCmebAPI, CmppCmebAPI.class, app.getAppId(), app.getAppId(), app.getRegistryAddress(),
//                Integer.valueOf(app.getDubboPort()));
        // 提供的Sms服务
//        CmppSmsAPI cmppSmsAPI = (CmppSmsAPI) context.getBean("cmppSmsApi");
        // 初始化很重要
//        cmppSmsAPI.init(this);
        this.app = getApp();
        start();
    }

    public static void main(String args[]) {

        CmppClient client = new CmppClient();
        client.runService();
    }

}
